package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.core.Promise

////////////////////
// Tab Groups
////////////////////
/**
 * Use the `Browser.tabGroups` API to interact with the browser's tab grouping system. You can use this API to modify and rearrange tab groups in the browser. To group and ungroup tabs, or to query what tabs are in groups, use the `Browser.tabs` API.
 *
 * Permissions: "tabGroups"
 * @since Chrome 89, MV3
 */
interface TabGroups {
    /** An ID that represents the absence of a group. */
    // default is -1
    val TAB_GROUP_ID_NONE: Int

    /**
     * Retrieves details about the specified group.
     *
     * Can return its result via Promise since Chrome 90.
     */
    @ChromeMinVersion(90)
    fun get(groupId: Number, callback: Value1Function<TabGroup>): Promise<Void>

    /**
     * Moves the group and all its tabs within its window, or to a new window.
     * @param groupId The ID of the group to move.
     *
     * Can return its result via Promise since Chrome 90.
     */
    @ChromeMinVersion(90)
    fun move(
        groupId: Number,
        moveProperties: MoveProperties,
        callback: Value1Function<TabGroup?>? = null
    ): Promise<TabGroup?>

    /**
     * Gets all groups that have the specified properties, or all groups if no properties are specified.
     *
     * Can return its result via Promise since Chrome 90.
     */
    @ChromeMinVersion(90)
    fun query(queryInfo: QueryInfo, callback: Value1Function<List<TabGroup>>? = null): Promise<Void>


    /**
     * Modifies the properties of a group. Properties that are not specified in `updateProperties` are not modified.
     * @param groupId The ID of the group to modify.
     *
     * Can return its result via Promise since Chrome 90.
     */
    @ChromeMinVersion(90)
    fun update(
        groupId: Number,
        updateProperties: UpdateProperties,
        callback: Value1Function<TabGroup?>? = null
    ): Promise<Void>

    /** Fired when a group is created. */
    val onCreated: Events.Event<Value1Function<TabGroup>>
    /** Fired when a group is moved within a window. Move events are still fired for the individual tabs within the group, as well as for the group itself. This event is not fired when a group is moved between windows; instead, it will be removed from one window and created in another. */
    val onMoved: Events.Event<Value1Function<TabGroup>>
    /** Fired when a group is closed, either directly by the user or automatically because it contained zero tabs. */
    val onRemoved: Events.Event<Value1Function<TabGroup>>
    /** Fired when a group is updated. */
    val onUpdated: Events.Event<Value1Function<TabGroup>>


    /** The group's color. */
    enum class Color {
        blue,
        cyan,
        green,
        grey,
        orange,
        pink,
        purple,
        red,
        yellow
    }

    data class TabGroup(
        /** Whether the group is collapsed. A collapsed group is one whose tabs are hidden. */
        var collapsed: Boolean,
        /** The group's color. */
        var color: Color,
        /** The ID of the group. Group IDs are unique within a browser session. */
        var id: Number,
        /**
         * Whether the group is shared.
         * @since Chrome 137
         */
        var shared: Boolean,
        /** The title of the group. */
        var title: String?,
        /** The ID of the window that contains the group. */
        var windowId: Number
    )

    data class MoveProperties(
        /** The position to move the group to. Use `-1` to place the group at the end of the window. */
        var index: Number,
        /** The window to move the group to. Defaults to the window the group is currently in. Note that groups can only be moved to and from windows with {@link windows.windowTypeEnum windows.windowType} type `"normal"`. */
        var windowId: Number?
    )

    data class QueryInfo(
        /** Whether the groups are collapsed. */
        var collapsed: Boolean?,
        /** The color of the groups. */
        var color: Color?,
        /**
         * Whether the group is shared.
         * @since Chrome 137
         */
        var shared: Boolean?,
        /** Match group titles against a pattern. */
        var title: String?,
        /** The ID of the parent window, or {@link windows.WINDOW_ID_CURRENT} for the current window. */
        var windowId: Number?
    )

    data class UpdateProperties(
        /** Whether the group should be collapsed. */
        var collapsed: Boolean?,
        /** The color of the group. */
        var color: Color?,
        /** The title of the group. */
        var title: String?
    )

}